basicmicrofandomcom-20200214-history
MBasic: Branching and Subroutines
Branching and Subroutines Intro This chapter includes the "normal" BASIC commands that are included with most versions of BASIC, as well as commands specific to Atom BASIC. Read it carefully: some familiar commands may be defined somewhat differently in Atom BASIC. This chapter contains the following sections: * Branching and Subroutines ** Branch ** Goto ** Gosub...return ** exception ** If...then...else Conventions Used in this Chapter GOTO Unconditionally forces program execution to jump to the supplied label. The line following the GOTO command is not executed unless it is a label referenced from elsewhere in the program. Syntax :goto label ::label is the label at which program execution should continue Examples This sample program shows one of many possible uses of the goto command: :variables and constants defined here :start ; beginning of program ::program code here :goto start ; loop back to start of program :firstsub ; beginning of subroutine section ::subroutines here BRANCH BRANCH is an indexed form of GOTO. Branch uses an index number to choose from a list of labels, then jumps to that label. Syntax :branch index,[label1, label2, label3,...] ::index is a variable or constant pointing within the list of labels, with counting starting at zero. ::labels are any valid labels in your program If "index" is greater than the number of labels in the list, no jump will occur and program execution will continue with the next line. Examples If the value of variable "test" is 3, :branch test,cold, raise, lower, adjust, terminate will cause program execution to jump to the line labeled "lower". GOSUB... RETURN Note:' Atom Pro Basic now supports parameter passing to subroutines. See below. GOSUB stores a return address on the "stack" and jumps to the specified label (which should be the label of a subroutine). The subroutine must end with a RETURN command. RETURN retrieves and removes from the stack the address stored by GOSUB, and resumes program execution on the line following the original GOSUB command. ''Important: Subroutines should exit via the RETURN command which clears the saved address from the stack. (If a subroutine exits without using RETURN or EXCEPTION the saved address will remain on the stack. If such subroutines are executed many times the stack may overflow.) If multiple exit points are required from a subroutine, use the EXCEPTION command described below. Do not use BRANCH or GOTO to exit a subroutine.'' '''''Syntax :gosub label ::label is the label of any valid subroutine in the program :return or :gosub label parameters value ::parameters are values to be passed as arguments for the subroutine returned value will contain the value passed back by the subroutine return returned value Note:' All variables are global in scope. '''''Example 1 val var word weightmin var word weightmax var word start code to calculate minimum weight hserout " val = weightmin gosub outvaldec code to calculate maximum weight hserout " val = weightmax gosub outvaldec goto start outvaldec hserout is ",dec val," mg",13 return The program calculates a minimum and maximum weight (perhaps using sensors) and displays output on a serial terminal in the format: :Minimum weight is 15 mg :Maximum weight is 32 mg The intermediate variable val is used to pass the output value. Example 2 returnval var sbyte gosub myfunction3,1,5,returnval ;returnval = -1 arg1 var sbyte arg2 var sbyte arg3 var sbyte result var sbyte myfunction arg1,arg2,arg3 result = arg1+arg2-arg3 return result This example calculates a result based on the passed parameters, and returns the result (-1 in the example) as returnval. Note:' result and returnval need not have the same name. '''''Example 3 You can use just the return argument: gosub myfunc2 returnval myfunc2 return 3 Example 4 Or you can use just the arguments: gosub myfunc33,2 arg1 var sbyte arg2 var sbyte myfunc3arg1,arg2 high arg1 low arg2 return Warning:' The compiler does not verify that your call to a function has the same number or types of arguments as your function is expecting. If they do not match, it is very likely that memory will be corrupted and your program may reset. The reset may happen immediately or it could happen at a later time EXCEPTION You should never use the GOTO command to leave a subroutine as this will leave the return address on the stack and if this is done enough times will probably fault the processor. If you encounter a case in your program where you wish to exit the subroutine but not have the program continue at the line following th gosub statement you should instead use the EXCEPTION command. EXCEPTION differs from RETURN as follows: '''''Syntax :exception label ::label is the label at which program execution should continue Examples val var word weightmin var word weightmax var word start code to calculate minimum weight hserout " val = weightmin gosub outvaldec code to calculate maximum weight hserout " val = weightmax gosub outvaldec goto start outvaldec ; start of subroutine if weightmin > 5 then continue exception start ; value is too low - do again continue hserout is ",dec val," mg",13 return This program is similar to the one under GOSUB but provides an "escape" from the subroutine if the minimum weight is too low. IF... THEN... ELSEIF... ELSE... ENDIF This set of commands provides conditional GOTO and/or GOSUB capability. The IF... THEN commands can be used in two formats: simple and extended. Syntax - Simple Format :if comparison then label ::comparison is a statement that can be evaluated as true or false, for example x = 7, temp <> 13, etc. ::label marks the program line which will be executed next if the comparison is true The comparison is evaluated. If it is true, program execution passes to the line marked by the specified label. If it is false program control continues with the next line following the IF... THEN line. :if comparison then gosub label Behaves as above except that a GOSUB rather than a GOTO is performed if the comparison is true. Example a var byte statements to set value of a if a > 35 then limit statements will execute if a <= 35 limit statements If a <= 35 the statements immediately following the IF... THEN line will execute. Otherwise control will jump to the label "limit". Syntax - Extended Format :if comparison1 then ::statements (executed if comparison1 is true, then jumps to the line following ENDIF. If false, jumps to ELSE or ELSEIF.) :elseif comparison2 then ::statements (executed if comparison 1 is false but comparison 2 is true, then jumps to the line following ENDIF. If false, jumps to the next ELSEIF or to ELSE.) :else ::statements (executed if neither comparison1 nor comparison2 is true) :endif Note that elseif and else are optional. See the examples below. Examples IF THEN ELSEIF ELSEIF ELSEIF ELSEIF ENDIF ant var byte bat var word array var byte(20) {code setting value of a} if ant < 5 then array = "small" bat = 100 elseif ant < 10 array = "medium" bat = 1000 else array = "big" bat = 10000 endif If the first comparison (ant < 5) is true the next two statements are executed and then program execution passes to the line following ENDIF. If the first comparison is false, the next two statements are skipped and program execution passes to the "elseif" line. ''Note: Multiple "elseif" lines may be included if necessary.'' If the second comparison is true, the next two lines are executed and program execution then passes to the line following ENDIF. If the second comparison is false, the next two lines are skipped and program execution passes to the "else" line. The statements following the "else" line are executed until the "endif" is reached. ant var byte bat var word start code setting value of ant if ant < 5 then small elseif ant < 10 then medium endif goto big small code to process small value goto start medium code to process medium value goto start big code to process big value goto start This code provides a 3 way "switch" depending on the value of "ant". The line following "goto big" should be a label referenced from elsewhere in the program or it will not be executed.